/**
 * Indexer.java
 * com.tempus.ubp.dps.newsearch.base
 *
 * Function： TODO 
 *
 *   ver     date      		author
 * ──────────────────────────────────
 *   		 2016年11月24日 		chenyingchun
 *
 * Copyright (c) 2016, TNT All Rights Reserved.
*/

package com.uoko.common.collection;

import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.function.Function;


/**
 * <p>
 *
 * </p>
 *
 * @author chenyingchun
 * Email qiaohai@uoko.com
 * created by 2018/6/6 0006
 */
public class MultiMap<K, V> implements IMultiMap<K, V>{

	public static <K, V> MultiMap<K, V> create() {
		return new MultiMap<K, V>();
	}

	/**
	 * 
	 */
	private Map<K, Set<V>> multiMap = Collections.createMap();

	/**
	 * 获取或者创建一个key。
	 * 
	 * @param key
	 * @return
	 */
	private Set<V> getOrCreateIndexSet(K key) {

		Set<V> set = this.multiMap.get(key);
		if (set == null) {
			set = Collections.createSet();
			this.multiMap.put(key, set);
		}
		return set;

	}

	@Override
	public void put(K key, V value) {

		getOrCreateIndexSet(key).add(value);

	}

	@Override
	public void putAll(K key, Collection<V> values) {

		getOrCreateIndexSet(key).addAll(values);
	}

	@Override
	public void remove(K key, V value) {

		Set<V> set = get(key);
		if (set != null) {
			set.remove(value);
		}

	}

	@Override
	public void removeAll(K key) {

		 
		this.multiMap.remove(key);

	}

	@Override
	public Set<V> get(K key) {

		return this.multiMap.get(key);

	}

	@Override
	public void clear() {

		this.multiMap.clear();

	}

	@Override
	public boolean isEmpty() {
		return this.multiMap.isEmpty();
	}

	@Override
	public boolean containsKey(K key) {

		return this.multiMap.containsKey(key);
	}

	@Override
	public boolean containsEntry(K key, V value) {
		Set<V> set = get(key);
		return (set != null && set.contains(value));
	}

	@Override
	public Collection<V> replaceValues(K key, Iterable<? extends V> values) {
		// throw new Exception("该功能未提供！");
		return null;
	}

	@Override
	public Set<K> keySet() {

		return this.multiMap.keySet();
	}

	@Override
	public Integer count(K key) {
		Set<V> tempSet = this.get(key);
		if (tempSet != null)
			return tempSet.size();
		else
			return 0;
	}

	/**
	 * tomap,通用用于对集合建立索引;
	 * 
	 * @param list
	 * @param action
	 * @return
	 */
	public static <K, V> MultiMap<K, V> toMap(Collection<V> list, Function<V, K> action) {

		if (list == null || list.isEmpty())
			return null;
		MultiMap<K, V> resMap = new MultiMap<>();
		list.forEach((value) -> {
			resMap.put(action.apply(value), value);
		});
		return resMap;
	}

	@Override
	public Set<Entry<K, Set<V>>> entrySet() {
	 
		return this.multiMap.entrySet();
	}
	
}
